package com.huangjue.backend.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.huangjue.backend.constant.ResponseFormats;
import com.huangjue.backend.dto.aiChatClient.AiRequestMessage;
import com.huangjue.backend.dto.aiChatClient.ClientRequest;
import com.huangjue.backend.dto.aiChatClient.ClientResponse;
import com.huangjue.backend.entity.HomeworkAnalysis;
import com.huangjue.backend.entity.Homework;
import com.huangjue.backend.entity.HomeworkDemand;
import com.huangjue.backend.entity.HomeworkEvaluation;
import com.huangjue.backend.mapper.HomeworkAnalysisMapper;
import com.huangjue.backend.mapper.HomeworkDemandMapper;
import com.huangjue.backend.mapper.HomeworkEvaluationMapper;
import com.huangjue.backend.mapper.HomeworkMapper;
import com.huangjue.backend.service.AiService;
import com.huangjue.backend.utils.ClientRequestBuilder;
import com.huangjue.backend.utils.HttpHeaderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.http.*;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import static com.huangjue.backend.constant.PromptWords.CodeReviewPrompts.AI_CODE_REVIEWER_PROMPT;
import static com.huangjue.backend.constant.PromptWords.CodeReviewPrompts.AI_CODE_REVIEWER_PROMPT_v2;
import static com.huangjue.backend.constant.PromptWords.HOMEWORK_CHECK;

@Service
public class AiServiceImpl implements AiService {

//    private final String apiKey;
//    private final String apiUrl;
    private final RestTemplate restTemplate;
    private final WebClient webClient;
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final HomeworkAnalysisMapper homeworkAnalysisMapper;
    private final HomeworkDemandMapper homeworkDemandMapper;
    private final HomeworkMapper homeworkMapper;
    private final HomeworkEvaluationMapper homeworkEvaluationMapper;
    @Autowired
    public AiServiceImpl(RestTemplate restTemplate,
                         Environment env,
                         WebClient.Builder webClientBuilder,
                         HomeworkAnalysisMapper homeworkAnalysisMapper,
                         HomeworkDemandMapper homeworkDemandMapper,
                         HomeworkMapper homeworkMapper,
                         HomeworkEvaluationMapper homeworkEvaluationMapper) {

        this.homeworkMapper = homeworkMapper;
        this.restTemplate = restTemplate;
//        this.apiKey = env.getProperty("llm.deepseek.apiKey");
//        this.apiUrl = env.getProperty("llm.deepseek.apiUrl");

        // 配置WebClient（用于流式请求）
        HttpClient httpClient = HttpClient.create()
                .responseTimeout(Duration.ofMinutes(10));

        this.webClient = webClientBuilder
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
        this.homeworkAnalysisMapper = homeworkAnalysisMapper;
        this.homeworkDemandMapper = homeworkDemandMapper;
        this.homeworkEvaluationMapper = homeworkEvaluationMapper;
    }

    @Value("${llm.deepseek.apiKey}")
    private String apiKey;

    @Value("${llm.deepseek.apiUrl}")
    private String apiUrl;

    @Value("${llm.deepseek.model}")
    private String chatModel;

    @Override
    public ClientResponse  defaultCall(String systemPrompt, String userInput, double temperature,
                                       String ResponseFormat, Collection<AiRequestMessage> history){
        HttpHeaders headers = HttpHeaderUtil.createJsonBearerHeaders(apiKey);
        // 2. 构建请求体
        try {
            ClientRequestBuilder builder = new ClientRequestBuilder()
                    .model(chatModel)
                    .system(systemPrompt)
                    .user(userInput)
                    .temperature(temperature)
                    .stream(false);

            if (history != null && !history.isEmpty()) {
                builder.addAll(history);
            }

            ClientRequest req = builder.build();
            // 3. 发送请求
            HttpEntity<ClientRequest> requestEntity = new HttpEntity<>(req, headers);
            ResponseEntity<ClientResponse> response = restTemplate.exchange(
                    apiUrl,
                    HttpMethod.POST,
                    requestEntity,
                    ClientResponse.class
            );

            return response.getBody();
        } catch (IllegalArgumentException e) {
            System.err.println("请求体构建失败: " + e.getMessage());
        }
        return null;
    }

    @Override
    public Flux<String> callStream(String systemPrompt, String userInput, double temperature, String ResponseFormat, Collection<AiRequestMessage> history) {
        HttpHeaders headers = HttpHeaderUtil.createJsonBearerHeaders(apiKey);
        try {
            ClientRequestBuilder builder = new ClientRequestBuilder()
                    .model(chatModel)
                    .system(systemPrompt)
                    .user(userInput)
                    .temperature(temperature)
                    .stream(true);

            if (history != null && !history.isEmpty()) {
                builder.addAll(history);
            }

            // 用于缓存不完整的JSON数据
            AtomicReference<StringBuilder> fullContent = new AtomicReference<>(new StringBuilder());
            ClientRequest req = builder.build();

            System.out.println(req);
            // 3. 使用WebClient发送流式请求
            return webClient.post()
                    .uri(apiUrl)
                    .headers(httpHeaders -> httpHeaders.addAll(headers))
                    .bodyValue(req)
                    .retrieve()
                    .bodyToFlux(String.class)
//                    .doOnNext(line -> System.out.println("原始响应: " + line))
                    .filter(line -> !line.trim().isEmpty() && !line.trim().equals("[DONE]"))
                    .onErrorResume(e -> Flux.error(new RuntimeException("大模型调用失败", e)))
                    .flatMap(json -> {
                        try {
                            Map<String, Object> response = objectMapper.readValue(json, Map.class);
                            List<Map<String, Object>> choices = (List<Map<String, Object>>) response.get("choices");
                            if (choices != null && !choices.isEmpty()) {
                                Map<String, Object> choice = choices.get(0);
                                Map<String, Object> delta = (Map<String, Object>) choice.get("delta");
                                // 处理首次响应（包含角色信息）
                                if (delta != null) {
                                    String content = (String) delta.get("content");
                                    // 返回有效内容
                                    if (content != null) {
//                                        System.out.println("返回响应：" + content);
                                        fullContent.get().append(content);
                                        return Mono.just(content);
                                    }
                                }
                            }
//                        System.out.println("返回空响应");
                            return Mono.just("");
                        } catch (Exception e) {
//                        System.err.println("JSON解析错误: " + json);
                            return Mono.just("[解析错误]");
                        }
                    })
                    .doOnComplete(() -> {
                        // 流结束时处理完整内容
                        String completeResponse = fullContent.get().toString();
                        System.out.println("完整响应内容: " + completeResponse);
                    });

        }catch (IllegalArgumentException e) {
            System.err.println("请求体构建失败: " + e.getMessage());
        }catch (RuntimeException e) {
            System.err.println("API 流式调用失败:"+e.getMessage());
        }
        return null;
    }

    @Override
    public Map<String, Object> assignmentScore(String code,int userId, int homeworkId) {
        Map<String, Object> responseToController = new HashMap<>();
        try {
            // 按作业ID查询作业要求
            Homework homework =  homeworkMapper.selectById(homeworkId);
            HomeworkDemand demand = homeworkDemandMapper.selectByHomeworkId(homeworkId);

            String systemPrompt = "作业要求如下：" + homework.getDescription() + "\n" + AI_CODE_REVIEWER_PROMPT;

            String response = String.valueOf(this.defaultCall(systemPrompt,code,0, ResponseFormats.TEXT,null));

            String cleaned = response
                    .replaceFirst("^\\s*```json\\s*", "")  // 移除开头的```json
                    .replaceFirst("\\s*```\\s*$", "")       // 移除结尾的```
                    .trim();
            Gson gson = new Gson();
            JsonObject json = gson.fromJson(cleaned, JsonObject.class);
            // 创建实体对象
            HomeworkAnalysis analysis = new HomeworkAnalysis();

            // 设置基本字段
            analysis.setUserId(userId);
            analysis.setHomeworkId(homeworkId);
            analysis.setHomeworkScore(json.get("score").getAsString());
            analysis.setHomeworkGrade(json.get("grade").getAsString());
            analysis.setEncouragement(json.get("encouragement").getAsString());
            JsonObject breakdown = json.getAsJsonObject("breakdown");
            analysis.setBreakdown(gson.toJson(breakdown)); // 关键修复：序列化整个对象
            analysis.setCorrectnessScore(breakdown.getAsJsonObject("correctness").get("score").getAsInt());
            analysis.setQualityScore(breakdown.getAsJsonObject("quality").get("score").getAsInt());
            analysis.setOptimizationScore(breakdown.getAsJsonObject("optimization").get("score").getAsInt());
            analysis.setAttitudeScore(breakdown.getAsJsonObject("attitude").get("score").getAsInt());
            analysis.setHighlights(gson.toJson(json.getAsJsonArray("highlights")));
            analysis.setImprovements(gson.toJson(json.getAsJsonArray("improvements")));
            analysis.setLearningTips(gson.toJson(json.getAsJsonArray("learning_tips")));

            // 插入数据库
            int result = homeworkAnalysisMapper.insert(analysis);
            if (result > 0) {
                responseToController.put("code", 200);
                responseToController.put("message", "Success");
                responseToController.put("data", cleaned);
            } else {
                responseToController.put("code", 500);
                responseToController.put("message", "数据库插入失败");
                responseToController.put("data", "数据库插入失败");
            }
        } catch (Exception e) {
            responseToController.put("code", 500);
            responseToController.put("message", "Analysis failed: " + e.getMessage());
            responseToController.put("data", e.getMessage());
        }

        return responseToController;
    }

    //作业评分v2版本,存入数据库中用于给智能体进行作业情况分析
    @Override
    public Map<String, Object> homework_summary(String code, int userId, int homeworkId){
        Map<String, Object> responseToController = new HashMap<>();
        // 按作业ID查询作业要求
        Homework homework =  homeworkMapper.selectById(homeworkId);

        String systemPrompt = "作业要求如下：" + homework.getDescription() + "\n" + AI_CODE_REVIEWER_PROMPT_v2;
        ClientResponse response = this.defaultCall(systemPrompt,code,0, ResponseFormats.JSON_OBJECT,null);
//        System.out.println(response);
        String aiResponse = response.getChoices().get(0).getMessage().getContent();
//        System.out.println(aiResponse);
        Gson gson = new Gson();
        try {
            // 解析AI返回的JSON内容
            JsonObject json = gson.fromJson(aiResponse, JsonObject.class);
            HomeworkEvaluation evaluation = new HomeworkEvaluation();

            // 设置基础信息
            evaluation.setUserId(userId);
            evaluation.setHomeworkId(homeworkId);
            evaluation.setCourseId(homework.getCourseId());

            // 处理字符串类型字段
            evaluation.setScore(json.get("score").getAsString());
            evaluation.setGrade(json.get("grade").getAsString());
            evaluation.setEncouragement(json.get("encouragement").getAsString());

            // 处理数组类型字段（转换为JSON字符串存储）
            JsonArray highlightsArray = json.getAsJsonArray("highlights");
            evaluation.setHighlights(gson.toJson(highlightsArray));

            JsonArray excellentSnippets = json.getAsJsonArray("excellent_code_snippets");
            evaluation.setExcellentCodeSnippets(gson.toJson(excellentSnippets));

            JsonArray problemSnippets = json.getAsJsonArray("problem_code_snippets");
            evaluation.setProblemCodeSnippets(gson.toJson(problemSnippets));

            JsonArray knowledgePoints = json.getAsJsonArray("knowledge_points_mapping");
            evaluation.setKnowledgePointsMapping(gson.toJson(knowledgePoints));

            JsonArray improvements = json.getAsJsonArray("improvements");
            evaluation.setImprovements(gson.toJson(improvements));

            JsonArray learningTips = json.getAsJsonArray("learning_tips");
            evaluation.setLearningTips(gson.toJson(learningTips));

            // 处理对象类型字段（转换为JSON字符串存储）
            JsonObject breakdown = json.getAsJsonObject("breakdown");
            evaluation.setBreakdownJson(gson.toJson(breakdown));

            homeworkEvaluationMapper.insert(evaluation);
            responseToController.put("code", 200);
            responseToController.put("message", "评价处理成功");
            responseToController.put("data", evaluation);
        } catch (Exception e) {
            responseToController.put("code", 500);
            responseToController.put("message", "评价处理失败: " + e.getMessage());
            e.printStackTrace();
        }
        return responseToController;
    }

    @Override
    public Map<String, Object> checkHomework(String code, int userId, int homeworkId) {
        Map<String, Object> responseToController = new HashMap<>();
        // 按作业ID查询作业要求
        Homework homework = homeworkMapper.selectById(homeworkId);

        String systemPrompt = HOMEWORK_CHECK + homework.getDescription() + "\n" + "以下是用户提交的作业：" + "\n" + code;
//        System.out.println(systemPrompt);
        ClientResponse response = this.defaultCall(systemPrompt, code, 0, ResponseFormats.JSON_OBJECT, null);

//        System.out.println(response.getChoices().get(0).getMessage().getContent());
        Gson gson = new Gson();
        if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) {
//            System.err.println("AI 响应为空或无有效返回结果");
            responseToController.put("code", 500);
            responseToController.put("message", "AI 响应异常");
            return responseToController;
        }

        // 解析 AI 返回的顶层 JSON
        String aiContent = String.valueOf(response.getChoices().get(0).getMessage().getContent());
        JsonObject json = gson.fromJson(aiContent, JsonObject.class);
        //        System.out.println("AI 返回的完整 JSON：" + json);

        // 1. 先获取嵌套的 result 对象
        JsonElement resultElement = json.get("result");
        if (resultElement == null || !resultElement.isJsonObject()) {
            responseToController.put("code", 500);
            responseToController.put("message", "AI 返回格式异常（缺少 result）");
            return responseToController;
        }
        JsonObject resultObj = resultElement.getAsJsonObject(); // 拿到 result 内部的 JSON 对象

        // 2. 处理 is_pass
        JsonElement isPassElement = json.get("is_pass");
        if (isPassElement == null) {
            responseToController.put("code", 500);
            responseToController.put("message", "AI 返回格式异常（缺少 is_pass）");
            return responseToController;
        }
        boolean isPass = isPassElement.getAsBoolean();
        String isPassStr = String.valueOf(isPass);
        responseToController.put("is_pass", isPassStr);

        // 3. 从 resultObj 中获取需求字段（不再从顶层 json 获取！）
        if (isPass) {
            // 从 resultObj 拿 metRequirements
            JsonElement metRequirements = resultObj.get("metRequirements");
            responseToController.put("metRequirements", metRequirements != null ? metRequirements.toString() : "[]");
            // 从 resultObj 拿 needRequirements
            JsonElement needRequirements = resultObj.get("needRequirements");
            responseToController.put("needRequirements", needRequirements != null ? needRequirements.toString() : "[]");
        } else {
            // 从 resultObj 拿 unmetRequirements
            JsonElement unmetRequirements = resultObj.get("unmetRequirements");
            responseToController.put("unmetRequirements", unmetRequirements != null ? unmetRequirements.toString() : "[]");
            // 从 resultObj 拿 needRequirements
            JsonElement needRequirements = resultObj.get("needRequirements");
            responseToController.put("needRequirements", needRequirements != null ? needRequirements.toString() : "[]");
        }

        // 补充响应状态
        responseToController.put("code", 200);
        responseToController.put("message", "Success");
        return responseToController;
    }
}